const Reporter = require('../lib/reporter');
const semver = require('semver');
const os = require('os');
const path = require('path');
let osVersion = `${os.platform()}-${os.arch()}-${os.release()}`;

let getReleaseChannel = version => {
  return version.indexOf('beta') > -1
    ? 'beta'
    : version.indexOf('dev') > -1
    ? 'dev'
    : 'stable';
};

// describe('Reporter', () => {
//   let reporter,
//     requests,
//     initialStackTraceLimit,
//     initialHomeDirectory,
//     mockActivePackages;
//
//   beforeEach(() => {
//     reporter = new Reporter({
//       request: (url, options) => requests.push(Object.assign({ url }, options)),
//       alwaysReport: true,
//       reportPreviousErrors: false
//     });
//     requests = [];
//     mockActivePackages = [];
//     spyOn(atom.packages, 'getActivePackages').andCallFake(
//       () => mockActivePackages
//     );
//
//     initialStackTraceLimit = Error.stackTraceLimit;
//     Error.stackTraceLimit = 1;
//
//     initialHomeDirectory = process.env.HOME;
//   });
//
//   afterEach(() => {
//     process.env.HOME = initialHomeDirectory;
//     Error.stackTraceLimit = initialStackTraceLimit;
//   });
//
//   describe('.reportUncaughtException(error)', () => {
//     it('posts errors originated inside Pulsar Core to BugSnag', () => {
//       const repositoryRootPath = path.join(__dirname, '..');
//       reporter = new Reporter({
//         request: (url, options) =>
//           requests.push(Object.assign({ url }, options)),
//         alwaysReport: true,
//         reportPreviousErrors: false,
//         resourcePath: repositoryRootPath
//       });
//
//       let error = new Error();
//       Error.captureStackTrace(error);
//       reporter.reportUncaughtException(error);
//       let [lineNumber, columnNumber] = error.stack
//         .match(/.js:(\d+):(\d+)/)
//         .slice(1)
//         .map(s => parseInt(s));
//
//       expect(requests.length).toBe(1);
//       let [request] = requests;
//       expect(request.method).toBe('POST');
//       expect(request.url).toBe('https://notify.bugsnag.com');
//       expect(request.headers.get('Content-Type')).toBe('application/json');
//       let body = JSON.parse(request.body);
//       // Delete `inProject` field because tests may fail when run as part of Pulsar Core
//       // (i.e. when this test file will be located under `node_modules/exception-reporting/spec`)
//       delete body.events[0].exceptions[0].stacktrace[0].inProject;
//
//       expect(body).toEqual({
//         apiKey: Reporter.API_KEY,
//         notifier: {
//           name: 'Atom',
//           version: Reporter.LIB_VERSION,
//           url: 'https://www.atom.io'
//         },
//         events: [
//           {
//             payloadVersion: '2',
//             exceptions: [
//               {
//                 errorClass: 'Error',
//                 message: '',
//                 stacktrace: [
//                   {
//                     method: semver.gt(process.versions.electron, '1.6.0')
//                       ? 'Spec.<anonymous>'
//                       : '<anonymous>',
//                     file: 'spec/reporter-spec.js',
//                     lineNumber: lineNumber,
//                     columnNumber: columnNumber
//                   }
//                 ]
//               }
//             ],
//             severity: 'error',
//             user: {},
//             app: {
//               version: atom.getVersion(),
//               releaseStage: getReleaseChannel(atom.getVersion())
//             },
//             device: {
//               osVersion: osVersion
//             }
//           }
//         ]
//       });
//     });
//
//     it('posts errors originated outside Pulsar Core to BugSnag', () => {
//       process.env.HOME = path.join(__dirname, '..', '..');
//
//       let error = new Error();
//       Error.captureStackTrace(error);
//       reporter.reportUncaughtException(error);
//       let [lineNumber, columnNumber] = error.stack
//         .match(/.js:(\d+):(\d+)/)
//         .slice(1)
//         .map(s => parseInt(s));
//
//       expect(requests.length).toBe(1);
//       let [request] = requests;
//       expect(request.method).toBe('POST');
//       expect(request.url).toBe('https://notify.bugsnag.com');
//       expect(request.headers.get('Content-Type')).toBe('application/json');
//       let body = JSON.parse(request.body);
//       // Delete `inProject` field because tests may fail when run as part of Pulsar Core
//       // (i.e. when this test file will be located under `node_modules/exception-reporting/spec`)
//       delete body.events[0].exceptions[0].stacktrace[0].inProject;
//
//       expect(body).toEqual({
//         apiKey: Reporter.API_KEY,
//         notifier: {
//           name: 'Atom',
//           version: Reporter.LIB_VERSION,
//           url: 'https://www.atom.io'
//         },
//         events: [
//           {
//             payloadVersion: '2',
//             exceptions: [
//               {
//                 errorClass: 'Error',
//                 message: '',
//                 stacktrace: [
//                   {
//                     method: semver.gt(process.versions.electron, '1.6.0')
//                       ? 'Spec.<anonymous>'
//                       : '<anonymous>',
//                     file: '~/exception-reporting/spec/reporter-spec.js',
//                     lineNumber: lineNumber,
//                     columnNumber: columnNumber
//                   }
//                 ]
//               }
//             ],
//             severity: 'error',
//             user: {},
//             app: {
//               version: atom.getVersion(),
//               releaseStage: getReleaseChannel(atom.getVersion())
//             },
//             device: {
//               osVersion: osVersion
//             }
//           }
//         ]
//       });
//     });
//
//     describe('when the error object has `privateMetadata` and `privateMetadataDescription` fields', () => {
//       let [error, notification] = [];
//
//       beforeEach(() => {
//         atom.notifications.clear();
//         spyOn(atom.notifications, 'addInfo').andCallThrough();
//
//         error = new Error();
//         Error.captureStackTrace(error);
//
//         error.metadata = { foo: 'bar' };
//         error.privateMetadata = { baz: 'quux' };
//         error.privateMetadataDescription = 'The contents of baz';
//       });
//
//       it('posts a notification asking for consent', () => {
//         reporter.reportUncaughtException(error);
//         expect(atom.notifications.addInfo).toHaveBeenCalled();
//       });
//
//       it('submits the error with the private metadata if the user consents', () => {
//         spyOn(reporter, 'reportUncaughtException').andCallThrough();
//         reporter.reportUncaughtException(error);
//         reporter.reportUncaughtException.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//
//         let notificationOptions = atom.notifications.addInfo.argsForCall[0][1];
//         expect(notificationOptions.buttons[1].text).toMatch(/Yes/);
//
//         notificationOptions.buttons[1].onDidClick();
//         expect(reporter.reportUncaughtException).toHaveBeenCalledWith(error);
//         expect(reporter.reportUncaughtException.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar', baz: 'quux' });
//
//         expect(notification.isDismissed()).toBe(true);
//       });
//
//       it('submits the error without the private metadata if the user does not consent', () => {
//         spyOn(reporter, 'reportUncaughtException').andCallThrough();
//         reporter.reportUncaughtException(error);
//         reporter.reportUncaughtException.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//
//         let notificationOptions = atom.notifications.addInfo.argsForCall[0][1];
//         expect(notificationOptions.buttons[0].text).toMatch(/No/);
//
//         notificationOptions.buttons[0].onDidClick();
//         expect(reporter.reportUncaughtException).toHaveBeenCalledWith(error);
//         expect(reporter.reportUncaughtException.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar' });
//
//         expect(notification.isDismissed()).toBe(true);
//       });
//
//       it('submits the error without the private metadata if the user dismisses the notification', () => {
//         spyOn(reporter, 'reportUncaughtException').andCallThrough();
//         reporter.reportUncaughtException(error);
//         reporter.reportUncaughtException.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//         notification.dismiss();
//
//         expect(reporter.reportUncaughtException).toHaveBeenCalledWith(error);
//         expect(reporter.reportUncaughtException.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar' });
//       });
//     });
//
//     it('treats packages located in atom.packages.getPackageDirPaths as user packages', () => {
//       mockActivePackages = [
//         {
//           name: 'user-1',
//           path: '/Users/user/.atom/packages/user-1',
//           metadata: { version: '1.0.0' }
//         },
//         {
//           name: 'user-2',
//           path: '/Users/user/.atom/packages/user-2',
//           metadata: { version: '1.2.0' }
//         },
//         {
//           name: 'bundled-1',
//           path:
//             '/Applications/Atom.app/Contents/Resources/app.asar/node_modules/bundled-1',
//           metadata: { version: '1.0.0' }
//         },
//         {
//           name: 'bundled-2',
//           path:
//             '/Applications/Atom.app/Contents/Resources/app.asar/node_modules/bundled-2',
//           metadata: { version: '1.2.0' }
//         }
//       ];
//
//       const packageDirPaths = ['/Users/user/.atom/packages'];
//
//       spyOn(atom.packages, 'getPackageDirPaths').andReturn(packageDirPaths);
//
//       let error = new Error();
//       Error.captureStackTrace(error);
//       reporter.reportUncaughtException(error);
//
//       expect(error.metadata.userPackages).toEqual({
//         'user-1': '1.0.0',
//         'user-2': '1.2.0'
//       });
//       expect(error.metadata.bundledPackages).toEqual({
//         'bundled-1': '1.0.0',
//         'bundled-2': '1.2.0'
//       });
//     });
//
//     it('adds previous error messages and assertion failures to the reported metadata', () => {
//       reporter.reportPreviousErrors = true;
//
//       reporter.reportUncaughtException(new Error('A'));
//       reporter.reportUncaughtException(new Error('B'));
//       reporter.reportFailedAssertion(new Error('X'));
//       reporter.reportFailedAssertion(new Error('Y'));
//
//       reporter.reportUncaughtException(new Error('C'));
//
//       expect(requests.length).toBe(5);
//
//       const lastRequest = requests[requests.length - 1];
//       const body = JSON.parse(lastRequest.body);
//
//       console.log(body);
//       expect(body.events[0].metaData.previousErrors).toEqual(['A', 'B']);
//       expect(body.events[0].metaData.previousAssertionFailures).toEqual([
//         'X',
//         'Y'
//       ]);
//     });
//   });
//
//   describe('.reportFailedAssertion(error)', () => {
//     it('posts warnings to bugsnag', () => {
//       process.env.HOME = path.join(__dirname, '..', '..');
//
//       let error = new Error();
//       Error.captureStackTrace(error);
//       reporter.reportFailedAssertion(error);
//       let [lineNumber, columnNumber] = error.stack
//         .match(/.js:(\d+):(\d+)/)
//         .slice(1)
//         .map(s => parseInt(s));
//
//       expect(requests.length).toBe(1);
//       let [request] = requests;
//       expect(request.method).toBe('POST');
//       expect(request.url).toBe('https://notify.bugsnag.com');
//       expect(request.headers.get('Content-Type')).toBe('application/json');
//       let body = JSON.parse(request.body);
//       // Delete `inProject` field because tests may fail when run as part of Pulsar Core
//       // (i.e. when this test file will be located under `node_modules/exception-reporting/spec`)
//       delete body.events[0].exceptions[0].stacktrace[0].inProject;
//
//       expect(body).toEqual({
//         apiKey: Reporter.API_KEY,
//         notifier: {
//           name: 'Atom',
//           version: Reporter.LIB_VERSION,
//           url: 'https://www.atom.io'
//         },
//         events: [
//           {
//             payloadVersion: '2',
//             exceptions: [
//               {
//                 errorClass: 'Error',
//                 message: '',
//                 stacktrace: [
//                   {
//                     method: semver.gt(process.versions.electron, '1.6.0')
//                       ? 'Spec.<anonymous>'
//                       : '<anonymous>',
//                     file: '~/exception-reporting/spec/reporter-spec.js',
//                     lineNumber: lineNumber,
//                     columnNumber: columnNumber
//                   }
//                 ]
//               }
//             ],
//             severity: 'warning',
//             user: {},
//             app: {
//               version: atom.getVersion(),
//               releaseStage: getReleaseChannel(atom.getVersion())
//             },
//             device: {
//               osVersion: osVersion
//             }
//           }
//         ]
//       });
//     });
//
//     describe('when the error object has `privateMetadata` and `privateMetadataDescription` fields', () => {
//       let [error, notification] = [];
//
//       beforeEach(() => {
//         atom.notifications.clear();
//         spyOn(atom.notifications, 'addInfo').andCallThrough();
//
//         error = new Error();
//         Error.captureStackTrace(error);
//
//         error.metadata = { foo: 'bar' };
//         error.privateMetadata = { baz: 'quux' };
//         error.privateMetadataDescription = 'The contents of baz';
//       });
//
//       it('posts a notification asking for consent', () => {
//         reporter.reportFailedAssertion(error);
//         expect(atom.notifications.addInfo).toHaveBeenCalled();
//       });
//
//       it('submits the error with the private metadata if the user consents', () => {
//         spyOn(reporter, 'reportFailedAssertion').andCallThrough();
//         reporter.reportFailedAssertion(error);
//         reporter.reportFailedAssertion.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//
//         let notificationOptions = atom.notifications.addInfo.argsForCall[0][1];
//         expect(notificationOptions.buttons[1].text).toMatch(/Yes/);
//
//         notificationOptions.buttons[1].onDidClick();
//         expect(reporter.reportFailedAssertion).toHaveBeenCalledWith(error);
//         expect(reporter.reportFailedAssertion.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar', baz: 'quux' });
//
//         expect(notification.isDismissed()).toBe(true);
//       });
//
//       it('submits the error without the private metadata if the user does not consent', () => {
//         spyOn(reporter, 'reportFailedAssertion').andCallThrough();
//         reporter.reportFailedAssertion(error);
//         reporter.reportFailedAssertion.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//
//         let notificationOptions = atom.notifications.addInfo.argsForCall[0][1];
//         expect(notificationOptions.buttons[0].text).toMatch(/No/);
//
//         notificationOptions.buttons[0].onDidClick();
//         expect(reporter.reportFailedAssertion).toHaveBeenCalledWith(error);
//         expect(reporter.reportFailedAssertion.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar' });
//
//         expect(notification.isDismissed()).toBe(true);
//       });
//
//       it('submits the error without the private metadata if the user dismisses the notification', () => {
//         spyOn(reporter, 'reportFailedAssertion').andCallThrough();
//         reporter.reportFailedAssertion(error);
//         reporter.reportFailedAssertion.reset();
//
//         notification = atom.notifications.getNotifications()[0];
//         notification.dismiss();
//
//         expect(reporter.reportFailedAssertion).toHaveBeenCalledWith(error);
//         expect(reporter.reportFailedAssertion.callCount).toBe(1);
//         expect(error.privateMetadata).toBeUndefined();
//         expect(error.privateMetadataDescription).toBeUndefined();
//         expect(error.metadata).toEqual({ foo: 'bar' });
//       });
//
//       it("only notifies the user once for a given 'privateMetadataRequestName'", () => {
//         let fakeStorage = {};
//         spyOn(global.localStorage, 'setItem').andCallFake(
//           (key, value) => (fakeStorage[key] = value)
//         );
//         spyOn(global.localStorage, 'getItem').andCallFake(
//           key => fakeStorage[key]
//         );
//
//         error.privateMetadataRequestName = 'foo';
//
//         reporter.reportFailedAssertion(error);
//         expect(atom.notifications.addInfo).toHaveBeenCalled();
//         atom.notifications.addInfo.reset();
//
//         reporter.reportFailedAssertion(error);
//         expect(atom.notifications.addInfo).not.toHaveBeenCalled();
//
//         let error2 = new Error();
//         Error.captureStackTrace(error2);
//         error2.privateMetadataDescription = 'Something about you';
//         error2.privateMetadata = { baz: 'quux' };
//         error2.privateMetadataRequestName = 'bar';
//
//         reporter.reportFailedAssertion(error2);
//         expect(atom.notifications.addInfo).toHaveBeenCalled();
//       });
//     });
//
//     it('treats packages located in atom.packages.getPackageDirPaths as user packages', () => {
//       mockActivePackages = [
//         {
//           name: 'user-1',
//           path: '/Users/user/.atom/packages/user-1',
//           metadata: { version: '1.0.0' }
//         },
//         {
//           name: 'user-2',
//           path: '/Users/user/.atom/packages/user-2',
//           metadata: { version: '1.2.0' }
//         },
//         {
//           name: 'bundled-1',
//           path:
//             '/Applications/Atom.app/Contents/Resources/app.asar/node_modules/bundled-1',
//           metadata: { version: '1.0.0' }
//         },
//         {
//           name: 'bundled-2',
//           path:
//             '/Applications/Atom.app/Contents/Resources/app.asar/node_modules/bundled-2',
//           metadata: { version: '1.2.0' }
//         }
//       ];
//
//       const packageDirPaths = ['/Users/user/.atom/packages'];
//
//       spyOn(atom.packages, 'getPackageDirPaths').andReturn(packageDirPaths);
//
//       let error = new Error();
//       Error.captureStackTrace(error);
//       reporter.reportFailedAssertion(error);
//
//       expect(error.metadata.userPackages).toEqual({
//         'user-1': '1.0.0',
//         'user-2': '1.2.0'
//       });
//       expect(error.metadata.bundledPackages).toEqual({
//         'bundled-1': '1.0.0',
//         'bundled-2': '1.2.0'
//       });
//     });
//
//     it('adds previous error messages and assertion failures to the reported metadata', () => {
//       reporter.reportPreviousErrors = true;
//
//       reporter.reportUncaughtException(new Error('A'));
//       reporter.reportUncaughtException(new Error('B'));
//       reporter.reportFailedAssertion(new Error('X'));
//       reporter.reportFailedAssertion(new Error('Y'));
//
//       reporter.reportFailedAssertion(new Error('C'));
//
//       expect(requests.length).toBe(5);
//
//       const lastRequest = requests[requests.length - 1];
//       const body = JSON.parse(lastRequest.body);
//
//       expect(body.events[0].metaData.previousErrors).toEqual(['A', 'B']);
//       expect(body.events[0].metaData.previousAssertionFailures).toEqual([
//         'X',
//         'Y'
//       ]);
//     });
//   });
// });
